Skip to content

Fix federated reshares#58689

Open
provokateurin wants to merge 2 commits intomasterfrom
fix/federated-reshare
Open

Fix federated reshares#58689
provokateurin wants to merge 2 commits intomasterfrom
fix/federated-reshare

Conversation

@provokateurin
Copy link
Member

The following sharing chain didn't work before:

  1. User A from instances A creates public share link
  2. User B from instance B uses the "Add to your Nextcloud" feature
  3. User B from instance B creates a public share link
  4. User C from instance C uses the "Add to your Nextcloud" feature

Without these fixes step 4 fails:

$this->federatedShareProvider->create($share);
causes $share->setId($shareId); to be called on a share that already has an id set, which fails because it's not allowed. The share from user A to user B is also removed due to bad error handling after the exception.

I'm afraid the PublicOwnerWrapper is broken as well, because the code doesn't consider that the owner might be a user from a different instance, but I'm not sure if that can be fixed at all without huge changes. Maybe this scenario could be detected and the initiator could be used as a replacement, but that could also have other unintended side effects.

@provokateurin provokateurin added this to the Nextcloud 34 milestone Mar 3, 2026
@provokateurin provokateurin requested a review from a team as a code owner March 3, 2026 14:34
@provokateurin provokateurin added bug 3. to review Waiting for reviews labels Mar 3, 2026
@provokateurin provokateurin requested review from Altahrim, come-nc, leftybournes and salmart-dev and removed request for a team March 3, 2026 14:34
@provokateurin provokateurin force-pushed the fix/federated-reshare branch from dd38de7 to d999e97 Compare March 4, 2026 07:51
} catch (\Exception $e) {
// fall back to old re-share behavior if the remote server
// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
$this->removeShareFromTable($share);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix: I think that removing this will lead to a stale entry in oc_share if the remote call fails for any reason with an Exception

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this was always wrong. Basically when resharing fails, the original share was also deleted. This was a separate bug besides the fact that resharing didn't work in the first place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original share was deleted because the code causing the exception was setId, but the row in oc_share for Server B to Server C got created in the line above. If the request to the original server fails, we should remove that row, otherwise Server B displays that the file is shared with Server C, but that might not be true.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could still be a case where the remote server managed to store the share information but failed afterwards, so removing the share here could lead to an inconsistency in that case, which in connection with my other comment could lead to still having a broken situation 🤔

Copy link
Contributor

@come-nc come-nc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @salmart-dev I think. For the rest, approved.

Signed-off-by: provokateurin <kate@provokateurin.de>
…r might on another server

Signed-off-by: provokateurin <kate@provokateurin.de>
} catch (\Exception $e) {
// fall back to old re-share behavior if the remote server
// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
$this->removeShareFromTable($share);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original share was deleted because the code causing the exception was setId, but the row in oc_share for Server B to Server C got created in the line above. If the request to the original server fails, we should remove that row, otherwise Server B displays that the file is shared with Server C, but that might not be true.

} catch (\Exception $e) {
// fall back to old re-share behavior if the remote server
// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
$this->removeShareFromTable($share);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There could still be a case where the remote server managed to store the share information but failed afterwards, so removing the share here could lead to an inconsistency in that case, which in connection with my other comment could lead to still having a broken situation 🤔

$this->storeRemoteId($shareId, $remoteId);
} else {
$this->removeShareFromTable($share);
$this->removeShareFromTable($shareId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment: noticing that there is no handling for the case where the oc_share entry was missing but the remote had a matching share. This could happen if the current server's DB would be restored to a state without that specific row. I don't see any code that would handle a "share already exists on the remote, track it on this server" but I may have missed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants